package com.movies.service.controller.user;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.movies.service.common.Result;
import com.movies.service.entity.Cinema;
// 新增导入：座位实体与服务、JSON 序列化
import com.movies.service.entity.Seat;
import com.movies.service.service.CinemaService;
import com.movies.service.service.SeatService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/user/cinema")
public class UserCinemaController {

    @Autowired
    private CinemaService cinemaService;

    @Autowired
    private SeatService seatService;

//    分页查询影院列表（支持名称模糊、状态筛选）
    @GetMapping("/page")
    public Result page(@RequestParam(defaultValue = "1") Integer pageNo,
                       @RequestParam(defaultValue = "10") Integer pageSize,
                       @RequestParam(required = false) String cname,
                       @RequestParam(required = false) String status) {
        LambdaQueryWrapper<Cinema> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(cname != null && !cname.isEmpty(), Cinema::getCname, cname)
                .eq(status != null && !status.isEmpty(), Cinema::getStatus, status);
        Page<Cinema> page = cinemaService.page(new Page<>(pageNo, pageSize), wrapper);
        return Result.success(page);
    }

//    关键字搜索影院（按名称或地址）
    @GetMapping("/search")
    public Result search(@RequestParam String keyword,
                         @RequestParam(defaultValue = "1") Integer pageNo,
                         @RequestParam(defaultValue = "10") Integer pageSize) {
        LambdaQueryWrapper<Cinema> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Cinema::getCname, keyword).or().like(Cinema::getAddress, keyword);
        Page<Cinema> page = cinemaService.page(new Page<>(pageNo, pageSize), wrapper);
        return Result.success(page);
    }

//    获取影院详情
    @GetMapping("/{id}")
    public Result get(@PathVariable Long id) {
        Cinema c = cinemaService.getById(id);
        if (c == null) {
            return Result.success(null);
        }
        String hallRaw = c.getHallList();
        List<String> hallList = null;
        try {
            if (hallRaw != null && !hallRaw.trim().isEmpty() && !"null".equalsIgnoreCase(hallRaw.trim())) {
                ObjectMapper mapper = new ObjectMapper();
                hallList = mapper.readValue(hallRaw, new TypeReference<List<String>>(){});
            }
        } catch (Exception ignored) {
            hallList = null;
        }
        // 若 hallList 仍为空，则根据座位表派生影厅名称集合
        if (hallList == null || hallList.isEmpty()) {
            LambdaQueryWrapper<Seat> sw = new LambdaQueryWrapper<>();
            sw.eq(Seat::getCinemaId, id);
            List<String> halls = seatService.list(sw).stream()
                    .map(Seat::getHallName)
                    .filter(s -> s != null && !s.isEmpty())
                    .distinct()
                    .collect(Collectors.toList());
            try {
                ObjectMapper mapper = new ObjectMapper();
                c.setHallList(mapper.writeValueAsString(halls));
            } catch (Exception e) {
                // 兜底：序列化失败时返回空数组字符串，避免编译/运行时报错
                c.setHallList("[]");
            }
        } else {
            try {
                ObjectMapper mapper = new ObjectMapper();
                c.setHallList(mapper.writeValueAsString(hallList));
            } catch (Exception e) {
                c.setHallList("[]");
            }
        }
        return Result.success(c);
    }

//    影院影厅与座位一览
    @GetMapping("/{id}/halls")
    public Result halls(@PathVariable Long id) {
        LambdaQueryWrapper<Seat> w = new LambdaQueryWrapper<>();
        w.eq(Seat::getCinemaId, id);
        List<Seat> all = seatService.list(w);
        java.util.Map<String, java.util.List<Seat>> grouped = all.stream()
                .filter(s -> s.getHallName() != null && !s.getHallName().isEmpty())
                .collect(java.util.stream.Collectors.groupingBy(Seat::getHallName));
        java.util.List<HallView> data = grouped.entrySet().stream().map(e -> {
            String hall = e.getKey();
            List<Seat> seats = e.getValue();
            java.util.List<SeatView> sv = seats.stream().map(s -> {
                String type = s.getSeatType() == null ? "NORMAL" : String.valueOf(s.getSeatType());
                return new SeatView(s.getSeatNo(), type);
            }).collect(java.util.stream.Collectors.toList());
            int seatCount = sv.size();
            int vipCount = (int) sv.stream().filter(x -> "VIP".equalsIgnoreCase(x.getSeatType())).count();
            return new HallView(hall, seatCount, vipCount, sv);
        }).collect(java.util.stream.Collectors.toList());
        return Result.success(data);
    }

    /** 影厅视图 DTO */
    public static class HallView {
        private String hallName;
        private Integer seatCount;
        private Integer vipCount;
        private java.util.List<SeatView> seats;
        public HallView(String hallName, Integer seatCount, Integer vipCount, java.util.List<SeatView> seats) {
            this.hallName = hallName; this.seatCount = seatCount; this.vipCount = vipCount; this.seats = seats;
        }
        public String getHallName() { return hallName; }
        public Integer getSeatCount() { return seatCount; }
        public Integer getVipCount() { return vipCount; }
        public java.util.List<SeatView> getSeats() { return seats; }
    }
    /** 座位视图 DTO */
    public static class SeatView {
        private String seatNo;
        private String seatType; // NORMAL/VIP
        public SeatView(String seatNo, String seatType) { this.seatNo = seatNo; this.seatType = seatType; }
        public String getSeatNo() { return seatNo; }
        public String getSeatType() { return seatType; }
    }
}